package com.huawei.cloudapp.utils;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class CasHttpUtils {

    public static final String TAG = "CasHttpUtils";
    public static final MediaType JSON = MediaType.get("application/json");

    public static void post(String url, Map<String, String> header, String json, Handler handler, int msgCode) {
        RequestBody body = RequestBody.create(json, JSON);
        Request.Builder builder = new Request.Builder();

        if (header != null && !header.isEmpty()) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.url(url)
                .post(body)
                .build();

        OKHttpClientBuilder.buildOKHttpClient().build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Message message = new Message();
                message.what = msgCode;
                message.obj = null;
                handler.sendMessage(message);
                Log.e(TAG, "Failed to get response.");
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                Message message = new Message();
                message.what = msgCode;
                message.obj = response.body().string();
                handler.sendMessage(message);
            }
        });
    }

    public static void post(String url, Map<String, String> header, String bodyStr, Callback callback) {
        RequestBody body = RequestBody.create(bodyStr, JSON);
        Request.Builder builder = new Request.Builder();

        if (header != null && !header.isEmpty()) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.url(url)
                .post(body)
                .build();

        OKHttpClientBuilder.buildOKHttpClient()
                .callTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(30, TimeUnit.SECONDS)
                .build().newCall(request).enqueue(callback);
    }

    public static void get(String url, Map<String, String> header, Callback callback) {
        Request.Builder builder = new Request.Builder();
        if (header != null && !header.isEmpty()) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

        Request request = builder.url(url)
                .build();

        OKHttpClientBuilder.buildOKHttpClient()
                .callTimeout(10, TimeUnit.SECONDS)
                .connectTimeout(30, TimeUnit.SECONDS)
                .build().newCall(request).enqueue(callback);
    }

    public static class OKHttpClientBuilder {
        public static OkHttpClient.Builder buildOKHttpClient() {
            try {
                TrustManager[] trustAllCerts = buildTrustManagers();
                final SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

                final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
                builder.hostnameVerifier((hostname, session) -> true);
                return builder;
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                e.printStackTrace();
                return new OkHttpClient.Builder();
            }
        }

        private static TrustManager[] buildTrustManagers() {
            return new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };
        }
    }

}
